package com.learning.thread.juc.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ClassName: ReentrantLockTest
 * Description: 重入锁 ReentrantLock
 * Date: 2016/11/26 17:45
 *
 * @author SAM SHO
 * @version V1.0
 */
public class ReentrantLockApi {

    /**
     * 定义锁对象
     */
    static final Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        new Thread(createTask(), "thread_1 ").start();
        Thread thread_2 = new Thread(createTask(), "thread_2 ");
        thread_2.start();

        Thread.sleep(600);
        // 中断
        // 单独调用interrupt()方法不能中断正在运行过程中的线程，只能中断阻塞过程中的线程
        thread_2.interrupt();
    }


    /**
     * 一次测试 Api 方法
     *
     * @return
     */
    public static Runnable createTask() {
        return new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {

//                        if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
                        if (lock.tryLock()) {
//                             lock.lock();
//                        lock.lockInterruptibly();

                            try {
                                System.out.println("locked by " + Thread.currentThread().getName());
                                Thread.sleep(1000L);
                            } finally {
                                // 需要手动解锁，一定要注意
                                lock.unlock();
                                System.out.println("unlocked by " + Thread.currentThread().getName());
                            }

                            // 正常一个线程在获得锁、等待1s、释放锁，然后会break循环
                            break;

                            // else 这段代码 lock.lock(); lock.lockInterruptibly(); 不需要
                        } else {
                            System.out.println("unable to lock " + Thread.currentThread().getName());
                        }


                    } catch (InterruptedException e) {
                        System.out.println(Thread.currentThread().getName() + "is Interrupted");
                    }

                }
            }
        };
    }
}

/*

单独调用 interrupt() 方法不能中断正在运行过程中的线程，只能中断阻塞过程中的线程
thread_2.interrupt();


1、lock.tryLock(500, TimeUnit.MILLISECONDS) 输出：

locked by thread_1
unable to lock thread_2 // 在规定时间内等待锁
thread_2 is Interrupted // 中断
unlocked by thread_1
locked by thread_2 // 中断结束后，继续尝试获得锁
unlocked by thread_2

2、lock.tryLock() 输出
locked by thread_1
unable to lock thread_2
.......................     // 一堆获取不到锁的信息, 因为锁被thread_1 占着。tryLock 不会等待，立即返回
unable to lock thread_2
unlocked by thread_1        // 解锁后，另一个线程 thread_2 才能得到锁
locked by thread_2          // 得到锁
unlocked by thread_2
thread_2 is Interrupted     // 在释放锁后被中断
locked by thread_2          // 由于被中断，跳过了break，继续请求锁
unlocked by thread_2

3、lock.lock() 输出：

locked by thread_1
unlocked by thread_1
locked by thread_2          // 等待获得锁，一直等待。等待的过程中不会响应线程中断
unlocked by thread_2        //
thread_2 is Interrupted     // 释放锁后,原本应该是break，但是响应了中断
locked by thread_2
unlocked by thread_2

4、lock.lockInterruptibly() 输出：

locked by thread_1
thread_2 is Interrupted     // 等待获得锁的过程中，响应了中断
unlocked by thread_1
locked by thread_2
unlocked by thread_2

 */
